package com.nodity.gui;

import java.awt.BasicStroke;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.Stroke;
import java.awt.event.MouseListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.lang.management.GarbageCollectorMXBean;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;

import com.nodity.structures.CharNode;

public class Display extends JComponent implements Runnable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@SuppressWarnings("rawtypes")
	public ArrayList<VisualCharNode> nodes=new ArrayList<VisualCharNode>();
	public ArrayList<NodeJoin> joins=new ArrayList<>();
	VisualCharNode nodeA,nodeB;
	boolean a,b;
	Canvas canvas;
	
	JPanel boo=new JPanel();
	JLabel label=new JLabel("Panel");
	
	enum VideoMode{
		drawing,notDrawing
	}
	
	static VideoMode vMode=VideoMode.notDrawing;


	private boolean running;

	public Display() {


		addMouseListener(new MouseListen());
		addMouseMotionListener(new MouseListen());
		addKeyListener(new KeyboardListen());
		setFocusable(true);
		boo.setBackground(Color.BLUE);
		add(boo);
		boo.setLocation(100,100);
		boo.setSize(50,50);
		boo.add(label);
		
		Thread s=new Thread(this);
		s.start();

	}

	public void paintComponent(Graphics g){
		vMode=VideoMode.drawing;
		super.paintComponent(g);
		g.setColor(Color.BLACK);
		g.drawString(String.valueOf(MouseListen.mouseCoords), 10, 20);
		g.drawString(String.valueOf(MouseListen.mouseState), 10, 40);
		g.drawString(String.valueOf(KeyboardListen.state), 10, 60);
		


		for(VisualCharNode n:nodes){
			n.display.renderNode(g);
			
			
		}



		for(NodeJoin nj:joins){
			nj.renderJoin(g);
		}



		if(a){
			g.setColor(Color.RED);
			g.drawOval(nodeA.display.x, nodeA.display.y, nodeA.display.width, nodeA.display.height);
		}

		if(b){
			g.setColor(Color.BLUE);
			g.drawOval(nodeB.display.x, nodeB.display.y, nodeB.display.width, nodeB.display.height);
		}
		//		
		//		if(a && b){
		//			g.setColor(Color.GREEN);
		//			Graphics2D g2=(Graphics2D)g;
		//			 
		//			g2.drawLine(nodeA.display.x+nodeA.display.width/2,nodeA.display.y+nodeA.display.height/2,nodeB.display.x+nodeB.display.width/2,nodeB.display.y+nodeA.display.height/2);
		//		
		//			   
		//			   
		//			    
		//		}
		repaint();
		vMode=VideoMode.notDrawing;

	}

	public void updateDisplay(){





		// create a node
		if(MouseListen.mouseState==MouseState.mouseLeftClick && KeyboardListen.state==ActionMode.createNode){



			VisualCharNode cn=new VisualCharNode(MouseListen.mouseCoords.x,MouseListen.mouseCoords.y,'g');

			nodes.add(cn);
			Point p=new Point(MouseListen.mouseCoords.x-cn.display.width/2,MouseListen.mouseCoords.y-cn.display.height/2);
			cn.display.setLocation(p);
			MouseListen.mouseState=MouseState.mouseDrawing;

		}


		// selecting nodes and lines
		if(MouseListen.mouseState==MouseState.mouseDown1 && KeyboardListen.state==ActionMode.selectMode){
			for(VisualCharNode n:nodes){
				n.display.setSelected(MouseListen.mouseCoords);
			}
			for(NodeJoin j:joins){
				j.setSelected(MouseListen.mouseCoords);
			}
		}


		// move a node
		if(MouseListen.mouseState==MouseState.mouseDrag && KeyboardListen.state==ActionMode.selectMode){
			for(VisualCharNode n:nodes){
				if(n.display.selected){
					Point p=new Point(MouseListen.mouseCoords.x-n.display.width/2,MouseListen.mouseCoords.y-n.display.height/2);

					n.display.setLocation(p);
				}
			}
			boo.setLocation(MouseListen.mouseCoords);
		}


		// delete a node
		if(MouseListen.mouseState==MouseState.mouseRightClick && KeyboardListen.state==ActionMode.deleteNode){

			VisualCharNode toDelete = null;
			for(VisualCharNode n:nodes){
				if(n.display.selected){
					toDelete=n;
				}
			}

			if(toDelete !=null){
				nodes.remove(toDelete);
				System.out.println("Node removed.");
			}
		}



		// start to create a line
		if(MouseListen.mouseState==MouseState.mouseLeftClick && KeyboardListen.state==ActionMode.createLine){

			Point p=new Point(MouseListen.mouseCoords);
			if(nodeA==null && nodeB==null){


				for(VisualCharNode n:nodes){
					if(n.display.contains(p)){
						nodeA=n;
						a=true;
						System.out.println(n.toString());
					}
				}

			}else if(nodeA!=null && nodeB==null){
				for(VisualCharNode n:nodes){
					if(!nodeA.equals(n)){
						if(n.display.contains(p)){
							nodeB=n;
							b=true;
							System.out.println(n.toString());
						}
					}
				}
			}else if(nodeA!=null && nodeB!=null){

				joins.add(new NodeJoin(nodeA.display.x,nodeA.display.y,nodeB.display.x,nodeB.display.y));

				nodeA=null;
				nodeB=null;
				a=false;
				b=false;
			}else{
				nodeA=null;
				nodeB=null;
				a=false;
				b=false;
			}




			//	MouseListen.mouseState=MouseState.mouseMoving;

		}


		// draw a line end point
		if(MouseListen.mouseState==MouseState.mouseLeftClick && KeyboardListen.state==ActionMode.createLine){




		}




		// if drawing a line and the end point is not on a node, delete the join


		// deselect lines everything when the mouse is up
		if(MouseListen.mouseState==MouseState.mouseUp1 && KeyboardListen.state==ActionMode.createLine){
			for(NodeJoin j:joins){
				j.selected=false;
			}
		}


	}

	@Override
	public void run() {
		Graphics g=getGraphics();
		running=true;
		while(running){

			updateDisplay();
			//paintAll(g);

			try {
				Thread.sleep(17);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			
		}

	}


}



class VisualCharNode extends CharNode{

	public VisualNode display;

	public VisualCharNode(int x,int y, Character c) {
		super(c);

		display=new VisualNode(x, y,getCharacter());
		// TODO Auto-generated constructor stub
	}



}



